﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;

namespace Pixysoft.Security
{
    //http://www.cnblogs.com/csky/archive/2007/06/01/767909.html

    //http://www.taiwanren.com/blog/article.asp?id=47

    //编码特点：\u5927\u57ce\u5c0f\u683c\u6d4b\u8bd5\u4fe1\u606f
    public class UniCoder
    {
        private static volatile UniCoder instance;

        private static object syncRoot = new Object();

        public static UniCoder Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        instance = new UniCoder();
                    }
                }

                return instance;

            }
        }

        private string _ToGB(string content)
        {
            Regex objRegex = new Regex("&#(?<UnicodeCode>[\\d]{5});", RegexOptions.IgnoreCase);
            Match objMatch = objRegex.Match(content);
            StringBuilder sb = new StringBuilder(content);
            while (objMatch.Success)
            {
                string code = Convert.ToString(Convert.ToInt32(objMatch.Result("${UnicodeCode}")), 16);
                byte[] array = new byte[2];
                array[0] = (byte)Convert.ToInt32(code.Substring(2), 16);
                array[1] = (byte)Convert.ToInt32(code.Substring(0, 2), 16);

                sb.Replace(objMatch.Value, Encoding.Unicode.GetString(array));

                objMatch = objMatch.NextMatch();
            }
            return sb.ToString();
        }

        public string ToGB(string content)
        {
            StringBuilder result = new StringBuilder();

            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < content.Length; i++)
            {
                char c = content[i];

                if (c == '\\')
                {
                    i++;
                    builder.Append(content[++i]);
                    builder.Append(content[++i]);
                    builder.Append(content[++i]);
                    builder.Append(content[++i]);

                    continue;
                }


                if (builder.Length > 0)
                {
                    result.Append(RawToGB(builder.ToString()));

                    builder = new StringBuilder();
                }

                result.Append(c);
            }

            if (builder.Length > 0)
                result.Append(RawToGB(builder.ToString()));

            return result.ToString();
        }

        public string RawToGB(string content)
        {
            //59275bb6597dff01

            if (content.Length % 4 != 0)
                return content;

            StringBuilder result = new StringBuilder();

            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < content.Length; i++)
            {
                if (i % 4 == 0 && builder.Length > 0)
                {
                    string code = builder.ToString();
                    byte[] array = new byte[2];
                    array[0] = (byte)Convert.ToInt32(code.Substring(2), 16);
                    array[1] = (byte)Convert.ToInt32(code.Substring(0, 2), 16);
                    result.Append(Encoding.Unicode.GetString(array));
                    builder = new StringBuilder();
                }

                builder.Append(content[i].ToString());

            }

            if (builder.Length > 0)
            {
                string lastcode = builder.ToString();
                byte[] lastarray = new byte[2];
                lastarray[0] = (byte)Convert.ToInt32(lastcode.Substring(2), 16);
                lastarray[1] = (byte)Convert.ToInt32(lastcode.Substring(0, 2), 16);
                result.Append(Encoding.Unicode.GetString(lastarray));
            }

            return result.ToString();
        }

        public string ToUniCode(string my)
        {

            byte[] bytes = System.Text.Encoding.Unicode.GetBytes(my);
            string lowCode = "", temp = "";
            for (int i = 0; i < bytes.Length; i++)
            {
                if (i % 2 == 0)
                {
                    temp = System.Convert.ToString(bytes[i], 16);//取出元素4编码内容（两位16进制）
                    if (temp.Length < 2)
                        temp = "0" + temp;

                }
                else
                {
                    string mytemp = System.Convert.ToString(bytes[i], 16);
                    if (mytemp.Length < 2) mytemp = "0" + mytemp;
                    lowCode = lowCode + @"\u" + mytemp + temp;//取出元素4编码内容（两位16进制）

                }
            }
            return lowCode;
        }

        private void test()
        {
            string value = "\u6211\u4e24\u5e74\u51cf\u4e0b60\u65a4";
            Console.Write(ToGB(value));
        }
    }
}
